package co.yixiang.modules.shop.utils;


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Map工具类
 *
 * @author lhs
 * @version 1.0, 2016年7月23日 下午2:38:16 lhs 创建
 */
public class MapUtils {

  public static final char UNDERLINE = '_';

  /**
   * @param pmsVo 绑定的VO
   * @param excludeList 不需要设值的属性列表
   * @return Object
   * @Title: mapToEntity
   */
  public static Object mapToEntity(Map map, Object pmsVo, List<String> excludeList)
      throws Exception {

    // 获得传入vo的Class方法
    Class newClass = pmsVo.getClass();
    // 得到vo中所有的成员变量
    Field[] fs = newClass.getDeclaredFields();
    // 方法变量
    String methodName = null;
    // map的value值
    Object mapValue = null;
    // 参数类型
    String parameterType = null;
    // 查找方法时需要传入的参数
    Class[] parameterTypes = new Class[1];
    // 执行invoke方法时需要传入的参数
    Object[] args = new Object[1];
    // 取得Map的迭代器
    Iterator it = map.keySet().iterator();

    if (excludeList == null) {
      excludeList = new ArrayList<String>();
    }
    while (it.hasNext()) {
      // 取出map的key值
      String key = ((String) it.next());
      String transKey = "";
      // 处理数据库字段变量名里下划线和首字母大写

      transKey = underlineToCamel(key.toLowerCase());

      if (transKey != null) {
        for (int i = 0; i < fs.length; i++) {
          if (excludeList.contains(fs[i].getName())) {
            continue;
          }

          if (transKey.equals(fs[i].getName())) {
            // 拼set方法名
            methodName = "set"
                + firstLowerToUpper(transKey);
            try {
              // 得到vo中成员变量的类型
              parameterTypes[0] = fs[i].getType();
              parameterType = parameterTypes[0].toString();
              // 找到vo中的方法
              Method method = newClass.getDeclaredMethod(
                  methodName, parameterTypes);
              mapValue = map.get(key);
              if (mapValue == null) {
                args[0] = null;
                continue;
              }
              // 下面代码都是参数类型是什么，如果有需求可以自行增加
              // 当set方法中的参数为int或者Integer
              if (parameterTypes[0] == Integer.class
                  || parameterTypes[0] == int.class) {
                if (mapValue instanceof Integer) {
                  args[0] = mapValue;
                } else {

                  args[0] = Integer
                      .parseInt((String) mapValue);
                }

              }
              // 当set方法中的参数为long或者Long
              else if (parameterTypes[0] == Long.class
                      || parameterTypes[0] == long.class) {
                if (mapValue instanceof Long) {
                  args[0] = mapValue;
                } else {

                  args[0] = Long
                          .parseLong((String) mapValue);
                }
                // 当set方法中的参数为short或者Short
              }else if (parameterTypes[0] == Short.class
                        || parameterTypes[0] == short.class) {
                  if (mapValue instanceof Short) {
                    args[0] = mapValue;
                  } else {

                    args[0] = Short
                            .parseShort((String) mapValue);
                  }
                // 当set方法中的参数为Date
              }else if (parameterTypes[0] == Date.class) {
                if (mapValue instanceof Date) {
                  args[0] = mapValue;
                } else {
                  SimpleDateFormat sdf = new SimpleDateFormat(
                      "yyyy-MM-dd HH:mm:ss");
                  args[0] = sdf.parse((String) mapValue);
                }
                // 当set方法中的参数为Float
              } else if (parameterTypes[0] == double.class
                  || parameterTypes[0] == Double.class) {
                if (mapValue instanceof Double) {
                  args[0] = mapValue;
                } else {
                  args[0] = Double
                      .parseDouble((String) mapValue);
                }
                // 当set方法中的参数为其他
              } else if (parameterTypes[0] == String.class) {
                if (mapValue instanceof String[]) {
                  String[] tempArray = (String[]) mapValue;
                  String result = "";
                  for (int m = 0; m < tempArray.length; m++) {
                    result = result + tempArray[m] + ",";
                  }
                  result = result.substring(0,
                      result.length() - 1);
                  args[0] = result;

                } else {
                  args[0] = (String) mapValue;
                }
              } else {
                args[0] = mapValue;
              }
              // 执行set方法存储数据
              method.invoke(pmsVo, args);

            } catch (SecurityException e) {
              throw new SecurityException("[mapBind]安全异常：" + e);
            } catch (NoSuchMethodException e) {
              throw new NoSuchMethodException(
                  "[mapBind]Vo中无此方法异常" + e);
            } catch (IllegalArgumentException e) {
              throw new Exception("VO中" + key + "属性类型"
                  + parameterType + "与Map中值为" + mapValue
                  + "的类型不匹配");
            } catch (IllegalAccessException e) {
              throw new IllegalAccessException(
                  "[mapBind]IllegalAccessException异常");
            } catch (ParseException e) {
              throw new ParseException(
                  "[mapBind]ParseException异常", 0);
            }
          }
        }
      }
    }
    return pmsVo;
  }


  /**
   * 下划线转驼峰
   *
   * @return String
   * @Title: underlineToCamel
   */
  public static String underlineToCamel(String param) {
    if (param == null || "".equals(param.trim())) {
      return "";
    }
    int len = param.length();
    StringBuilder sb = new StringBuilder(len);
    for (int i = 0; i < len; i++) {
      char c = param.charAt(i);
      if (c == UNDERLINE) {
        if (++i < len) {
          sb.append(Character.toUpperCase(param.charAt(i)));
        }
      } else {
        sb.append(c);
      }
    }
    return sb.toString();
  }

  /**
   * 首字母大写
   *
   * @return String
   * @Title: underlineToCamel
   */
  public static String firstLowerToUpper(String param) {
    if (param == null || "".equals(param.trim())) {
      return "";
    }

    //下划线之前只有一个字母



    return param.replaceFirst(param.substring(0, 1), param.substring(0, 1).toUpperCase());
  }


  public static void main(String[] args) throws Exception {

  }

}
